import mplfinance as mpf
import pandas as pd
import numpy as np

# 很多字体不支持
# 标题格式，字体为中文字体，颜色为黑色，粗体，水平中心对齐
title_font = {
  # 'fontname': 'Times New Roman, SimSun', 
  'size':     '16',
  'color':    'black',
  'weight':   'bold',
  'va':       'bottom',
  'ha':       'center'
}
# 红色数字格式（显示开盘收盘价）粗体红色24号字
large_red_font = {
  # 'fontname': 'Times New Roman, SimSun',
  'size':     '24',
  'color':    'red',
  'weight':   'bold',
  'va':       'bottom'
}
# 绿色数字格式（显示开盘收盘价）粗体绿色24号字
large_green_font = {
  # 'fontname': 'Times New Roman, SimSun',
  'size':     '24',
  'color':    'green',
  'weight':   'bold',
  'va':       'bottom'
}
# 小数字格式（显示其他价格信息）粗体红色12号字
small_red_font = {
  # 'fontname': 'Times New Roman, SimSun',
  'size':     '12',
  'color':    'red',
  'weight':   'bold',
  'va':       'bottom'
}
# 小数字格式（显示其他价格信息）粗体绿色12号字
small_green_font = {
  # 'fontname': 'Times New Roman, SimSun',
  'size':     '12',
  'color':    'green',
  'weight':   'bold',
  'va':       'bottom'
}
# 标签格式，可以显示中文，普通黑色12号字
normal_label_font = {
  # 'fontname': 'Microsoft PhagsPa',
  'size':     '12',
  'color':    'black',
  'va':       'bottom',
  'ha':       'right'
}
# 普通文本格式，普通黑色12号字
normal_font = {
  # 'fontname': 'Times New Roman, SimSun',
  'size':     '12',
  'color':    'black',
  'va':       'bottom',
  'ha':       'left'
}


# 获取数据，处理数据
def read_data(filename):
  df = pd.read_csv('./files/history_A_stock_k_data.csv')
  df['Open'] = df['open']
  df['Close'] = df['close']
  df['High'] = df['high']
  df['Low'] = df['low']
  df['Volume'] = df['volume']
  df['Date'] = df['date']

  df['Date'] = pd.to_datetime(df['Date'])
  df.set_index(['Date'], inplace=True)
  return df

# 获取数据
df = read_data('./files/test02.csv')

df['MA5'] = df['Close'].rolling(window=5).mean()
df['MA10'] = df['Close'].rolling(window=10).mean()
df['MA20'] = df['Close'].rolling(window=20).mean()
df['MA60'] = df['Close'].rolling(window=60).mean()


df['Short_MA'] = df['Close'].rolling(window=12).mean()
df['Long_MA'] = df['Close'].rolling(window=26).mean()
df['DIF'] = df['Short_MA'] - df['Long_MA']        # 快线
df['DEA'] = df['DIF'].rolling(window=9).mean()    # 慢线
df['MACD'] = df['DIF'] - df['DEA']                # 柱子

# df['macd-s'] = df['DEA']
# df['macd-m'] = df['DIF']

df['macd-s'] = df['DIF']
df['macd-m'] = df['DEA']
df['macd-h'] = df['MACD']



# 设置线元素的颜色
my_color = mpf.make_marketcolors(
  up='r',
  down='g',
  edge='inherit',
  wick='inherit',
  volume='inherit'
)

# 自定义风格
my_style = mpf.make_mpf_style(
  marketcolors=my_color,
  figcolor='(0.82, 0.83, 0.85)',
  gridcolor='(0.82, 0.83, 0.85)',
  rc={'font.family': 'SimHei', 'axes.unicode_minus': 'False'}
)

print(df.columns)




# data是测试数据，可以直接下载后读取，在下例中只显示其中100个交易日的数据
plot_data = df
# 读取显示区间最后一个交易日的数据
last_data = plot_data.iloc[-1]
print(last_data)
print('--------------------------------------')
# 使用mpf.figure()函数可以返回一个figure对象，从而进入External Axes Mode，从而实现对Axes对象和figure对象的自由控制
fig = mpf.figure(style=my_style, figsize=(12, 8), facecolor=(0.82, 0.83, 0.85))
# 添加三个图表，四个数字分别代表图表左下角在figure中的坐标，以及图表的宽（0.88）、高（0.60）
ax1 = fig.add_axes([0.06, 0.25, 0.88, 0.60])
# 添加第二、三张图表时，使用sharex关键字指明与ax1在x轴上对齐，且共用x轴
ax2 = fig.add_axes([0.06, 0.15, 0.88, 0.10], sharex=ax1)
ax3 = fig.add_axes([0.06, 0.05, 0.88, 0.10], sharex=ax1)
# 设置三张图表的Y轴标签
ax1.set_ylabel('价格')
ax2.set_ylabel('数量')
ax3.set_ylabel('macd')
# 在figure对象上添加文本对象，用于显示各种价格和标题


fig.text(0.50, 0.94, 'sh.600508:--上海能源', **title_font)

fig.text(0.12, 0.90, '开/收: ', **normal_label_font)
fig.text(0.13, 0.90, f'{np.round(last_data["open"], 3)} / {np.round(last_data["close"], 3)}', **large_red_font)
fig.text(0.12, 0.86, '最后交易日期:', **normal_label_font)
fig.text(0.2, 0.86, f'{last_data.name.date()}', **normal_label_font)

# fig.text(0.33, 0.90, '涨跌幅:', **normal_label_font)
# # fig.text(0.38, 0.90, f'{last_data["change"]}', **small_red_font)
# fig.text(0.33, 0.86, '涨跌幅百分比:', **normal_label_font)
# fig.text(0.41, 0.86, f'{np.round(last_data["pctChg"], 2)}%', **small_red_font)


fig.text(0.40, 0.90, '高: ', **normal_label_font)
fig.text(0.42, 0.90, f'{last_data["high"]}', **small_red_font)
fig.text(0.40, 0.86, '低: ', **normal_label_font) 
fig.text(0.42, 0.86, f'{last_data["low"]}', **small_green_font)
fig.text(0.55, 0.90, '量(股): ', **normal_label_font)
fig.text(0.57, 0.90, f'{last_data["volume"]}', **normal_font)
fig.text(0.55, 0.86, '额(元): ', **normal_label_font)
fig.text(0.57, 0.86, f'{last_data["amount"]}', **normal_font)
fig.text(0.70, 0.90, '涨停: ', **normal_label_font)
# fig.text(0.74, 0.90, f'{last_data["upper_lim"]}', **small_red_font)
fig.text(0.70, 0.86, '跌停: ', **normal_label_font)
# fig.text(0.74, 0.86, f'{last_data["lower_lim"]}', **small_green_font)
fig.text(0.85, 0.90, '均价: ', **normal_label_font)
# fig.text(0.89, 0.90, f'{np.round(last_data["average"], 3)}', **normal_font)
fig.text(0.85, 0.86, '昨收: ', **normal_label_font)
fig.text(0.89, 0.86, f'{last_data["preclose"]}', **normal_font)



# 没有数据，暂时生成不了

# macd指标由diff线、dea线、macd柱线和零轴这“三线一轴”组成，其中macd指标m值代表柱线。投资者可以根据柱线的变化来分析个股。

# 1、红柱放到最大为波段性的顶部，可以考虑卖出；绿柱放到最大为波段性的底部可以考虑买入。

# 2、由红柱进入绿柱是卖出信号，由绿柱进入红柱是买入信号。

# 3、当macd柱线与股价顶背离形成之后，柱体不断的缩短，表明市场下跌动能开始释放，投资者应卖出手中的股票。

# 4、当macd柱线与股价顶背离形成之后，柱体由红柱不断缩短，再进入绿柱，柱体不断拉升，说明空方已经占据主要地位，股价即将大跌，
# 投资者应忍痛割肉，抛出手中股票。

# 5、在macd红绿柱中其柱体连续超过二个月为红柱，红柱越多后期上涨幅度越大，表明多方在步步为营，为后期的股价拉升打下扎实的基础，
# 一般这种情况会出现牛股。

# # 生成一个空列表用于存储多个addplot
ap = []

# 通过ax=ax1参数指定把新的线条添加到ax1中，与K线图重叠
# ap = mpf.make_addplot(plot_data[['MA5', 'MA10', 'MA20', 'MA60']], ax=ax1)
ap.append(mpf.make_addplot(plot_data[['MA5', 'MA60']], ax=ax1))


# 在ax3图表中绘制 MACD指标中的快线和慢线
ap.append(mpf.make_addplot(plot_data[['macd-m', 'macd-s']], ax=ax3))
# 使用柱状图绘制快线和慢线的差值，根据差值的数值大小，分别用红色和绿色填充
# 红色和绿色部分需要分别填充，因此先生成两组数据，分别包含大于零和小于等于零的数据
bar_r = np.where(plot_data['macd-h'] > 0, plot_data['macd-h'], 0)
bar_g = np.where(plot_data['macd-h'] <= 0, plot_data['macd-h'], 0)
# 使用柱状图填充（type='bar')，设置颜色分别为红色和绿色
ap.append(mpf.make_addplot(bar_r, type='bar', color='red', ax=ax3))
ap.append(mpf.make_addplot(bar_g, type='bar', color='green', ax=ax3))

print(plot_data)





# 调用mpf.plot()函数，注意调用的方式跟上一节不同，这里需要指定ax=ax1，volume=ax2，将K线图显示在ax1中，交易量显示在ax2中
mpf.plot(
  plot_data,
  ax=ax1,
  volume=ax2,
  type='candle',
  style=my_style,
  figratio=(5, 3), # figratio设置图形的纵横比，figscale设置图像的缩放比例，tight_layout设置图像为紧密布局；

  # 使用mav关键字绘制移动平均线：
  # ①对单个移动平均线使用标量
  # ②对多个移动平均线使用元组或整数列表

  addplot=ap,

  # mav=(5, 60),  
  # mav=(5, 30, 100),  
  # mav=(5, 10, 20, 60, 100, 200),  
)

fig.show()		
input("Press Enter to close...")


